//package com.qijian.plug.capacity.cost;
//
//import cn.hutool.core.collection.CollectionUtil;
//import com.qijian.common.core.domain.entity.ProjectPreCost;
//import com.qijian.common.utils.ObjectUtils;
//import com.qijian.finance.domain.Cost;
//import com.qijian.finance.domain.enums.CostTypeEnum;
//import com.qijian.maindata.domain.ProcessOrder;
//import com.qijian.maindata.domain.Project;
//import com.qijian.maindata.domain.vo.LineProcessBomVo;
//import com.qijian.maindata.service.ILineProcessService;
//import com.qijian.maindata.service.IProjectService;
//import lombok.RequiredArgsConstructor;
//import org.apache.commons.collections4.SetUtils;
//import org.springframework.stereotype.Component;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.math.BigDecimal;
//import java.util.*;
//import java.util.stream.Collectors;
//
///**
// * 预算成本
// *
// * @author qijian
// */
//@Component
//@RequiredArgsConstructor
//public class PreCost extends CostPlugWrapper<ProjectPreCost.Cost> {
//
//    private final IProjectService projectService;
//    private final ILineProcessService lineProcessService;
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void doSomething(List<Object> args) {
//        super.doSomething(args);
//    }
//
//    @Override
//    protected void operation(List<Object> args) {
//        String type = args.get(1).toString();
//        String dataType = args.get(2).toString();
//        // 人工成本
//        List<LineProcessBomVo> processVoList = new ArrayList<>();
//        // 外协成本
//        List<LineProcessBomVo> outVoList = new ArrayList<>();
//        // 项目列表
//        List<Project> projectList = new ArrayList<>(16);
//        if ("work".equals(dataType)) {
//            // 单个项目生成工单
//            List<ProcessOrder> processOrders = (List<ProcessOrder>) args.get(0);
//            Project project = projectService.getById(processOrders.get(0).getProjectId());
//            if (ObjectUtils.isNotNull(project)) {
//                projectList.add(project);
//                processVoList = lineProcessService.groupByTypeName(project.getBomId(), true, null, false);
//                outVoList = lineProcessService.groupByTypeName(project.getBomId(), true, null, true);
//            }
//        } else if ("project".equals(dataType)) {
//            // 批量生成工单
//            projectList = (List<Project>) args.get(0);
//            processVoList = lineProcessService.groupByTypeName(projectList.get(0).getBomId(), true, null, false);
//            outVoList = lineProcessService.groupByTypeName(projectList.get(0).getBomId(), true, null, true);
//        }
//
//        //generate cost
//        if (CollectionUtil.isNotEmpty(projectList)) {
//            Set<String> projectMachineSet = projectList.stream().map(a -> String.format("%s(%s#)", a.getProjectNo(), a.getMachineNo())).collect(Collectors.toSet());
//            //顶级历史记录
//            Map<String, Cost> topOld = super.costService.getTopHistoryDataMap(projectMachineSet);
//            //高级历史记录param
////            Set<String[]> highParams1 = projectMachineSet.stream().map(k -> new String[]{k, CostTypeEnum.PROCESS_ORDER_USERS.getVal()}).collect(Collectors.toSet());
////            Set<String[]> highParams2 = projectMachineSet.stream().map(k -> new String[]{k, CostTypeEnum.OUTBOUND_CONFIRM.getVal()}).collect(Collectors.toSet());
////            Set<String[]> highParams3 = projectMachineSet.stream().map(k -> new String[]{k, CostTypeEnum.MAIN_OUT.getVal()}).collect(Collectors.toSet());
////            Set<String[]> highParams = SetUtils.union(SetUtils.union(highParams1, highParams2), highParams3);
//
//            //高级历史记录
//            Map<String, Cost> highOld = super.costService.getHighHistoryDataMap(projectMachineSet,
//                    CostTypeEnum.PROCESS_ORDER_USERS,
//                    CostTypeEnum.OUTBOUND_CONFIRM,
//                    CostTypeEnum.MAIN_OUT);
//
//            //子级历史记录param
//            List<LineProcessBomVo> finalProcessVoList = processVoList;
//            List<LineProcessBomVo> finalOutVoList = outVoList;
//
//            Set<String[]> childParams1 = projectMachineSet.stream().map(
//                    k -> finalProcessVoList.stream().map(a -> new String[]{k, a.getProcessTypeName()}).collect(Collectors.toSet())).flatMap(Collection::stream).collect(Collectors.toSet());
//            Set<String[]> childParams3 = projectMachineSet.stream().map(
//                    k -> finalOutVoList.stream().map(a -> new String[]{k, a.getProcessTypeName()}).collect(Collectors.toSet())).flatMap(Collection::stream).collect(Collectors.toSet());
//
//
//            Set<String[]> childParams = SetUtils.union(childParams1, childParams3);
//            //子级历史记录
//            Map<String, Cost> childOld = super.costService.getChildHistoryDataMap(childParams);
//
//            for (String element : projectMachineSet) {
//                Cost top = getTopCost(topOld, element);
//                //重置
//                top.setBudgetCost(BigDecimal.ZERO);
//
//                Cost high = getHighCost(highOld, element, CostTypeEnum.PROCESS_ORDER_USERS, top);
//                lineProcessBomVoProcess(processVoList, childOld, element, top, high);
//
//                high = getHighCost(highOld, element, CostTypeEnum.MAIN_OUT, top);
//                lineProcessBomVoProcess(outVoList, childOld, element, top, high);
//            }
//            List<Cost> saveOrUpdateList = new ArrayList<>
//                    (topOld.size() + highOld.size() + childOld.size());
//            saveOrUpdateList.addAll(topOld.values());
//            saveOrUpdateList.addAll(highOld.values());
//            saveOrUpdateList.addAll(childOld.values());
//            super.saveOrUpdateBatch(saveOrUpdateList);
//        }
//    }
//
//    private void lineProcessBomVoProcess(List<LineProcessBomVo> outVoList, Map<String, Cost> childOld, String element, Cost top, Cost high) {
//        //重置
//        high.setBudgetCost(BigDecimal.ZERO);
//        for (LineProcessBomVo outProcess : outVoList) {
//            Cost child = getChildCost(childOld, element, outProcess.getProcessTypeName(), high);
//            child.setBudgetCost(outProcess.getWorkCost().multiply(BigDecimal.valueOf(outProcess.getCount())));
//            high.setBudgetCost(high.getBudgetCost().add(child.getBudgetCost()));
//            top.setBudgetCost(top.getBudgetCost().add(child.getBudgetCost()));
//        }
//    }
//}
